# R-MASM 翻译器的 GUI 界面

import tkinter as tk
from tkinter import ttk
import tkinter.filedialog
import tkinter.font as font

app = tk.Tk()
app.iconbitmap("R.ico")
app.title("R-MASM 2 Test Translator GUI")
app.geometry('800x630')

file_path_var = tk.StringVar()
file_path_var.set("./input.txt")
auto_copy_var = tk.IntVar()


def translate():
    from new_rmasm import SimpleTranslate, TranslateResult
    if auto_copy_var.get():
        app.clipboard_clear()
    # 读取
    try:
        res = SimpleTranslate(file_path_var.get())
        if res.error:
            raise Exception(res.error)
        if auto_copy_var.get():
            app.clipboard_append(res.result)
        if res.war:
            from tkinter import messagebox
            messagebox.showwarning("警告", res.war)

        result_text.delete(1.0, 'end')
        result_text.insert('end', res.result)
        result_text.config(fg='#000')

    except Exception as e:
        result_text.config(fg='#f00')
        result_text.delete(1.0, 'end')
        result_text.insert('end', str(e))
        return


def select_file():
    file = tkinter.filedialog.askopenfilename(title='选择文件')
    if not file:
        return
    file_path_var.set(file)
    translate_button.pack()


label1 = ttk.Label(app, textvariable=file_path_var)
label1.pack()

frame1 = ttk.Frame(app)
select_file_button = ttk.Button(frame1, width=10, text='选择文件', command=select_file)
select_file_button.pack(side='left')
translate_button = ttk.Button(frame1, width=30, text="翻译", command=translate)
translate_button.pack(side='left', ipady='12')
auto_copy_check = ttk.Checkbutton(frame1, text="翻译后自动复制", variable=auto_copy_var, onvalue=1, offvalue=0)
auto_copy_check.pack(side='left')

frame1.pack()

# 占位符
tk.Label(app).pack()

result_text = tkinter.Text(app, font=font.Font(family="Arial", size=14), height=24)
result_text.insert("end", """# 这是 R-MASM 2 测试版翻译器，以及示例代码。
# 支持的游戏版本：135
# 可视化翻译器版本：v0.1.1\n
# 协作开发联系 QQ 2293840045

# 下面是示例代码，复制到某个文件里试试吧。
# ==================================

# import 现在是这种语法：
# import "C:/test.txt"

# sensor 不能直接用点了
let enabled了吗 = switch1.sensor(@enabled)

# 简单的定义宏
define hello{
    print("HELLO!!!")
}

# 调用简单的宏
hello()

# comment 写会显示在结果中的注释，不用加注释前缀
comment("========  显示在结果中的注释！  ========")
# raw 直接写游戏内的原生语句
raw("set 还可以设置变量 233")

comment("========  定义包含参数和调用对象 self 的宏  ========")
# 这也是复刻之前的 show 宏命令
define 显示文字(内容){
    print(内容)
    print_flush(self) 
    # self 表示调用这个 显示文字 的 . 之前的东西
}

message1.显示文字("我被显示在message1上")

comment("========  宏返回值  ========")
define 找最大数(x,y){
    if x > y{
        result = x 
        # result 表示调用 找最大数 时接收返回值的变量
    }else{
        result = y
    }
}

结果 = 找最大数(123, 456) 

comment("========  临时变量  ========")
define 先加2再平方(num){
    let 临时变量 = num + 2
    # let xxx 是定义临时变量，可以let 的同时赋值
    result = 临时变量 * 临时变量
}
let 临时变量
# 注意两个 let 临时变量 在翻译结果中不是同一个变量。
临时变量 = 先加2再平方(25)
print(临时变量)

comment("========  临时变量在 raw 中  ========")
let temp = 123
raw("set a",temp)
comment("当然也支持在 comment 中",temp)

comment("========  while  ========")
当前 = 0
while 当前 <= 10{
    当前 += 1
    print(当前)
}
print_flush(message1)

comment([position],"========  for  ========")
for let 当前 = 1 ; 当前 < 10; 当前 += 1{
    # 在 for 的哪一行定义的变量 当前 属于这个 for 里面，外面不能用
    print(当前)
}
print_flush(message1)

# [position] 表示当前代码在结果中的行数
comment([position],"========  跳转  ========")
不重名的唯一标签:
jump 不重名的唯一标签
jump 不重名的唯一标签 if a > b
jump 不重名的唯一标签 if not x
jump 不重名的唯一标签 if y


comment([position],"========  重名标签跳转  ========")
重名标签:
jump + 重名标签 # + 表示向下跳
jump - 重名标签 # - 表示向上跳

# [position xxx] 可以和 jump 一样获取到某个标签的行数
comment(
    "那两个标签分别在",
    [position - 重名标签],
    "行 和",
    [position + 重名标签],"行")
重名标签:

comment([position],"========  复刻曾经的 call  ========")
define call(target){
    let temp = @counter + 3
    sp += 1
    cell1.write(sp, temp)
    @counter = target
}
call([position test_proj])
test_proj:

comment([position],"========  复刻曾经的 ret  ========")
define ret{
    let temp = cell1.read(sp)
    sp -= 1
    @counter = temp
}
ret()

comment([position],"========  十六进制和二进制  ========")
number = 10
number = 1010B
number = 0xA


comment([position],"========  仿函数式编程  ========")
define if_switch_on(switch,code){
    let temp = switch.sensor(@enabled)
    if temp{
        code()
    }
}
if_switch_on(switch1,{num += 1})


comment([position],"========  仿函数式编程，支持回调参数（测试功能，实战需谨慎）  ========")

define if_switch_on_ext(switch,code){
    let temp = switch.sensor(@enabled)
    if temp{
        code(switch)
    }
}

if_switch_on_ext(switch1,(target_switch){
    let x = target_switch.sensor(@thisx)
    num += x
})

comment([position],"========  仿函数式编程，支持传递宏（本质是 bug，实战需谨慎）  ========")
# 如果知道 if_switch_on_ext 的代码参数叫做 code，可以直接定义一个 code
define code(switch){
        let x = switch.sensor(@thisx)
    num += x
}
# 然后这里的 code 位置填一个 null 或者任意无意义的东西。
# if_switch_on_ext 内部的 code(switch) 就会找到上面定义的 code。
# 注意要求名字和参数都相同才行。
if_switch_on_ext(switch123,0)
if_switch_on_ext(switch456,0)
if_switch_on_ext(switch999,0)
""")
result_text.pack()

app.mainloop()
